#ifndef ADI1787_H
#define ADI1787_H
#include <library.h>
#include <message.h>
#include <gaia.h>

/* pskey离线保存1787 ADC增益 */
#define i2c_addr_1787_8bit 0x50
#define adc_value_store_key 200
#define adc0_value_key 201
#define adc1_value_key 202
#define adc2_value_key 203
#define adc3_value_key 204
#define anc_state_key 205
#define light_sensor_enabled_key 206
#define pga01_value_key 207
#define pga11_value_key 208
#define pga21_value_key 209
#define pga31_value_key 210
#define anc_adaptive_enabled_key 211
#define anc_on_state_key 212
#define anc_led_enabled_key 213
#define eq_ucid_key 214
#define my_peq_gain_key 215
/* ADI1787寄存器定义 */
#define ADI1787_REGISTERS
#ifdef ADI1787_REGISTERS
extern uint16 ADI1787_ADC_MUTE_REG;
extern uint16 ADI1787_DAC_MUTE_REG;
extern uint16 ADI1787_FASTDSP_RUN;
extern uint16 ADI1787_BANK_CONTROL_REG;
extern uint16 ADI1787_ADC0_VALUE_REG;
extern uint16 ADI1787_ADC1_VALUE_REG;
extern uint16 ADI1787_ADC2_VALUE_REG;
extern uint16 ADI1787_ADC3_VALUE_REG;
extern uint16 ADI1787_ADC_DAC_POWER;
extern uint16 ADI1787_MBIAS_PGA_POWER;
extern uint16 ADI1787_SAI_CLK_PWR;
extern uint16 ADI1787_POWER_CONTROL;
extern uint16 ADI1787_DAC0_ROUTE;
extern uint16 ADI1787_DAC1_ROUTE;
extern uint16 ADI1787_SPT0_CTRL;
extern uint16 ADI1787_MP_CTRL7;
extern uint16 ADI1787_MP_CTRL4;
extern uint16 ADI1787_ASRC_PWR;
extern uint16 ADI1787_DAC0_VOL;
extern uint16 ADI1787_SPT0_CTRL2;

extern uint8 ADC_MUTE[1];
extern uint8 ADC_UNMUTE[1];
extern uint8 VALUE_00[1];
extern uint8 VALUE_01[1];
extern uint8 VALUE_02[1];
extern uint8 VALUE_03[1];
extern uint8 VALUE_20[1];
extern uint8 VALUE_21[1];
extern uint8 VALUE_10[1];
extern uint8 VALUE_13[1];
extern uint8 VALUE_15[1];
extern uint8 VALUE_17[1];
extern uint8 VALUE_33[1];
extern uint8 VALUE_40[1];
extern uint8 VALUE_41[1];
extern uint8 VALUE_60[1];
extern uint8 ADC02_MUTE[1];
extern uint8 ADC13_MUTE[1];
extern uint8 ADC_POWER_OFF[1];
extern uint8 ADC_POWER_ON[1];
extern uint8 MBIAS_PGA_OFF[1];
extern uint8 MBIAS_PGA_ON[1];

extern uint8 ADC_Value_0[1];
extern uint8 ADC_Value_6[1];

extern uint8 BANK_A[1];
extern uint8 BANK_B[1];
extern uint8 BANK_C[1];

extern uint8 DAC_MUTE[1];
extern uint8 DAC_UNMUTE[1];
#endif
///////////////////////////////////////////////////    UART     ///////////////////////////////////////////////////////////////////////
#define SEND_MODE_UART 0
#define SEND_MODE_SPP 1
#define SEND_MODE_GAIA 2
extern bool spp_server_started;
#define UART_RECV_BUF_SIZE 50
extern uint8 rxbuf[UART_RECV_BUF_SIZE];
uint16 my_i2c_reg_read(int devAddress, int address, int length, uint8 *pData);
void set_light_sensor_enabled(bool mode);
void UartCommandHandle(uint8 mode);
void SPPCommandHandleForAiroha(gaia_transport *transport);
void app_uart_handler(Task t, MessageId id, Message msg);

///////////////////////////////////////////////////     ANC     ///////////////////////////////////////////////////////////////////////
/*1787 PD pin */
#ifndef ADI1787_PD_PIN
#define ADI1787_PD_PIN (1 << 3)
#endif
#define ANC_LED_PIN 1
/*1787 DAC 淡入淡出时间定义(ms) */
#define fade_in_delay 4
#define fade_out_delay 10
#define fade_between_delay 280
#define dec_faded_value 0x80
// #define anc_prompt_time  620
#define anc_prompt_time 1330

/* 通透模式是否还原产测校准后的ADC增益 */
#define restore_gain_in_bank_B 1

#define STATE_ANC_OFF 0
#define STATE_ANC_ON 1
#define STATE_MONITOR_ON 2
#define STATE_ANC_ON2 3
typedef enum
{
    EventMyAncOff,
    EventMyAncOn,
    EventMyMonitorOn,
    EventMyAncMildOn,
    EventMySetDacRoute,
    EventMyAncSetBankA,
    EventMyAncSetBankB,
    EventMyAncSetBankC,
    EventMyAncSetNotChangeBank,
    EventMyAncSetIisOnlyRegitser,
    EventMyAncDacFadeOut,
    EventMyAncDacFadeIn,
    EventMyEnterIisOnly,
    EventMyAncOnExeture,
    EventMyMonitorOnExeture,
    EventMyAncMildOnExeture,
    EventMyAdiPdSetDown,
    EventMyAdiSpt0SetUp,
    EventMyAdiSpt0SetDown,
    EventMyAdiSpt0Set12dB,
    EventMyAdiSpt0Set0dB,
    EventMyRestoreVolume,
    EventMyAncFuncMode,
    EventMyBatteryLowPrompt,
} ANC_Events;

typedef struct
{
    TaskData task;
} AncTaskData;
extern AncTaskData anc_tast;
extern Task hs_task1;

#define AncGetTaskData() (&anc_tast)
#define AncGetTask() (&anc_tast.task)

extern uint16 anc_state;
extern uint8 anc_is_changing;
extern uint8 play_tone_on_anc_changing;
extern uint8 anc_led_pin;
extern bool anc_led_enabled;
void Parst_Adi1787_init_Data(const uint8 *data_ptr, uint16 size);
uint16 i2c_reg_write(int devAddress, int address, int length, uint8 *pData);
uint16 ADI1787_Registers_write(int devAddress, int address, int length, uint8 *pData);
void Init_ADC_Value(void);
void save_power_off_ANC_state(void);
void Set_Dafault_ANC_State(void);
void disenable_anc_led(void);
void enable_anc_led(void);
void DAC_Fade_In(void);
void DAC_Fade_Out(void);
void Enter_IIS_Only(void);
void ANC_OFF(void);
void ANC_Normal_ON(void);
void ANC_Mild_ON(void);
void Monitor_ON(void);
void ANC_task_init(Task init_task);
void ANC_led_init(uint8 led_num);
void restore_volume(void);
void my_battery_low_prompt_indcation_start(void);
void my_battery_low_prompt_indcation_stop(void);
//////////////////////////////////////// Adaptive ANC ///////////////////////////////////////////
// #define ANC_ADAPTIVE_DEBUG
#ifdef ANC_ADAPTIVE_DEBUG

#ifndef DEBUG_PRINT_ENABLED
#define DEBUG_PRINT_ENABLED
#endif

#include <print.h>
#include <stdio.h>

#define ANC_ADAPTIVE_DEBUG_RAW(x) PRINT(x)
#define ANC_ADAPTIVE_DEBUG_INFO(x)               \
    {                                            \
        PRINT(("%s:%d - ", __FILE__, __LINE__)); \
        PRINT(x);                                \
    }

#else /* ANC_DEBUG_LIB */

#define ANC_ADAPTIVE_DEBUG_RAW(x)
#define ANC_ADAPTIVE_DEBUG_INFO(x)

#endif /* ANC_DEBUG_LIB */
#define ANC_ADAPTIVE_SUPPORTED 1      /* 是否支持自适应ANC */

typedef struct
{
    TaskData task;
} AncAdaptiveTaskData;
extern AncAdaptiveTaskData anc_adaptive_tast;

typedef struct
{
    uint16 adc_value_l;
    uint16 adc_value_m;
    uint16 adc_value_h;
} EnvironmentValueData;

typedef enum
{
    EventAncAdaptiveEnvDet = 0, /*环境声音检测，100ms一次*/
    EventAncAdaptiveEnvId,      /*环境识别，5000ms一次*/
    EventAncAdaptiveSetLevelHigh,
    EventAncAdaptiveSetLevelMid,
    EventAncAdaptiveSetLevelLow,
    EventAncAdaptiveStart,
    EventAncAdaptiveStop
} AncAdaptiveEvents;

typedef enum
{
    AncAdaptiveDisenabled,
    AncAdaptiveEnabled
} AncAdaptiveState;

typedef enum
{
    AncOnStateHigh, /* 嘈杂场景 */
    AncOnStateMid,  /* 均衡场景 */
    AncOnStateLow   /* 风噪场景 */
} AncOnState;

extern uint16 anc_adaptive_enabled;
extern uint8 anc_on_state;
#define AncAdaptiveGetTaskData() (&anc_adaptive_tast)
#define AncAdaptiveGetTask() (&anc_adaptive_tast.task)

void Anc_Adaptive_Set_Level_High(void);
void Anc_Adaptive_Set_Level_Mid(void);
void Anc_Adaptive_Set_Level_Low(void);
void ANC_Adaptive_Task_Init(void);
void ANC_Adaptive_Task_DeInit(void);
void ANC_Adaptive_Start(void);
void ANC_Adaptive_Stop(void);

#define GAIA_COMMAND_TYPE_MASK (0x7F00)
#define GAIA_COMMAND_TYPE_CONFIGURATION (0x0100)
#define GAIA_COMMAND_TYPE_CONTROL (0x0200)
#define GAIA_COMMAND_TYPE_STATUS (0x0300)
#define GAIA_COMMAND_TYPE_FEATURE (0x0500)
#define GAIA_COMMAND_TYPE_DATA_TRANSFER (0x0600)
#define GAIA_COMMAND_TYPE_DEBUG (0x0700)
#define GAIA_COMMAND_TYPE_VOICE_ASSISTANT (0x1000)
#define GAIA_COMMAND_TYPE_HOST_RELAY (0x2000)
#define GAIA_COMMAND_TYPE_NOTIFICATION (0x4000)

#define GAIA_COMMAND_SET_ANC_STATE (0x023A)
#define GAIA_COMMAND_GET_ANC_STATE (0x02BA)
#define GAIA_COMMAND_SET_WEAR_DETECTION (0x023B)
#define GAIA_COMMAND_GET_WEAR_DETECTION (0x02BB)
#define GAIA_COMMAND_SET_ANC_ON_STATE (0x023C)
#define GAIA_COMMAND_GET_ANC_ON_STATE (0x02BC)

#define GAIA_COMMAND_SET_EQ_CONTROL (0x0214)
#define GAIA_COMMAND_GET_EQ_CONTROL (0x0294)
#define GAIA_COMMAND_SAVE_EQ_PARAM (0x023D)
#define GAIA_COMMAND_SET_USER_EQ_PARAMETER (0x021A)
#define GAIA_COMMAND_GET_USER_EQ_PARAMETER (0x029A)
#define GAIA_COMMAND_GET_MY_PEQ_GAIN (0x02BD)
#define GAIA_COMMAND_AV_REMOTE_CONTROL (0x021F)
#define GAIA_COMMAND_VOLUME_GET_MUTE_STATE (0x02BF)

#define GAIA_COMMAND_GET_API_VERSION (0x0300)
#define GAIA_COMMAND_GET_CURRENT_RSSI (0x0301)
#define GAIA_COMMAND_GET_CURRENT_BATTERY_LEVEL (0x0302)
#define GAIA_COMMAND_GET_MODULE_ID (0x0303)
#define GAIA_COMMAND_GET_APPLICATION_VERSION (0x0304)
#define GAIA_COMMAND_GET_PEER_ADDRESS (0x030A)
#define GAIA_COMMAND_GET_TWS_FORCED_DOWNMIX_MODE (0x030B)
#define GAIA_COMMAND_GET_DFU_STATUS (0x0310)

#define GAIA_EVENT_NOTIFICATION (0x4003)

void gaia_set_transport(GAIA_TRANSPORT* transport);
GAIA_TRANSPORT* gaia_get_transport(void);
////////////////////////////////////////////////////////////////////////////////////////////////////
#endif // ADI1787_H
